package image.color;

/**
 * Used for saving memory storage. Stores the R, G, B values of a color as three shorts.
 * So for each Color_Short, 24 bits of memory is used (3 times 8-bit).
 * 
 * @author Shimu
 *
 */
public class Color_Short implements Color<Color_Short> {

	private short R, G, B;

	public Color_Short(int intRep) {
		R = (short) ((intRep >> 16) & 255);
		G = (short) ((intRep >> 8) & 255);
		B = (short) (intRep & 255);
	}

	public Color_Short(double R, double G, double B) {
		this.R = (short) R;
		this.G = (short) G;
		this.B = (short) B;
	}

	public Color_Short(Color_Short c) {
		R = (short) c.R;
		G = (short) c.G;
		B = (short) c.B;
	}

	@Override
	public void add(Color_Short c) {
		R += c.R;
		G += c.G;
		B += c.B;
	}

	public void add(double R, double G, double B) {
		this.R += R;
		this.G += G;
		this.B += B;
	}

	@Override
	public void subtract(Color_Short c) {
		R -= c.R;
		G -= c.G;
		B -= c.B;
	}

	public void subtract(double R, double G, double B) {
		this.R -= R;
		this.G -= G;
		this.B -= B;
	}

	@Override
	public void invert() {
		R = (short) -R;
		G = (short) -G;
		B = (short) -B;
	}

	@Override
	public void scale(double scale) {
		R *= scale;
		G *= scale;
		B *= scale;
	}

	@Override
	public int intRep() {
		return (65536 * R + 256 * G + B);
	}

	public boolean above(short threshold) {
		return above(threshold, threshold, threshold);
	}

	public boolean above(double RThreshold, double GThreshold, double BThreshold) {
		if ((R < RThreshold) || (G < GThreshold) || (B < BThreshold)) {
			return false;
		}
		return true;
	}

	public static Color_Short add(Color_Short c1, Color_Short c2) {
		return new Color_Short(c1.R + c2.R, c1.G + c2.G, c1.B + c2.B);
	}

	public static Color_Short subtract(Color_Short c1, Color_Short c2) {
		return new Color_Short(c1.R - c2.R, c1.G - c2.G, c1.B - c2.B);
	}

	public static Color_Short scale(Color_Short c, double scale) {
		return new Color_Short(c.R * scale, c.G * scale, c.B * scale);
	}

	@Override
	public void clamp() {
		if (R < 0) R = 0;
		else if (R > 255) R = 255;

		if (G < 0) G = 0;
		else if (G > 255) G = 255;

		if (B < 0) B = 0;
		else if (B > 255) B = 255;
	}
	
        @Override
	public String toString() {
		return "[" + R + ", " + G + ", " + B + "]";
	}

	public static void main(String[] args) {
		Color_Short c = new Color_Short(123, 21, 0);
		System.out.println(c);
		System.out.println(c.intRep());
		System.out.println(c.above(10, 10, 10));

		Color_Short c2 = new Color_Short(13, 95, 12);
		System.out.println(c2);
		System.out.println(c2.intRep());
		System.out.println(c2.above(10, 10, 10));

		Color_Short c3 = new Color_Short(-1);
		System.out.println(c3);
		System.out.println(c3.intRep());
		System.out.println(c3.above(10, 10, 10));

		Color_Short c4 = new Color_Short(1);
		System.out.println(c4);
		System.out.println(c4.intRep());
		System.out.println(c4.above(10, 10, 10));
	}

}
